package com.payment.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.payment.entity.po.PayOrder;
import com.payment.entity.vo.PayVO;
import com.payment.common.utils.*;
import com.payment.common.wxutils.HttpUtil;
import com.payment.common.wxutils.PayCommonUtil;
import com.payment.common.wxutils.WxConfigUtil;
import com.payment.common.wxutils.XMLUtil;
import com.payment.enums.WxTradeType;
import com.payment.mapper.PayOrderMapper;
import com.payment.service.WxService;
import org.apache.commons.collections.map.HashedMap;
import org.jdom.JDOMException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;


@Service("WxService")
public class WxServiceImpl implements WxService {
	private static final Logger logger = LoggerFactory.getLogger(WxServiceImpl.class);

	@Resource
	private WxConfigUtil wxConfigUtil;
	@Resource
	private TrainingServiceImpl triningService;
	@Resource
	private PayOrderMapper payOrderMapper;
	@Override
	public ResultDataDto weixinPayCode(PayVO payVO) {
		System.out.println("---------------微信 付款码 发起预支付,保存订单 热水商户号信息-------------------");
		String totalAmount = payVO.getTotalAmount();
		String orderNo = payVO.getOutTradeNo();
		String authCode = payVO.getAuthCode();
		String notify_url = "";
		if (StringUtils.isBlank(totalAmount) || StringUtils.isBlank(orderNo) || StringUtils.isBlank(authCode)) {
			return ResultDataDto.error("参数不能为空");
		}
		try {
			String trade_type = WxTradeType.MICROPAY.getName();// 交易类型 付款码支付

			String subject = payVO.getBody();
			String totalFee = AmountUtils.changeY2F(totalAmount);
			SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
			//商品描述
			packageParams.put("body", subject);// 商品描述
			// 商品详情
			JSONObject value = new JSONObject();
			value.put("goods_name", subject);
			value.put("quantity", "1");
			JSONObject scene_info = new JSONObject();
			scene_info.put("goods_detail", value);
			packageParams.put("mch_id", wxConfigUtil.getMCH_ID());// 商户号*/
			packageParams.put("appid", wxConfigUtil.getAPP_ID());// 公众账号ID
			packageParams.put("detail", scene_info.toString());
			packageParams.put("nonce_str", WxConfigUtil.getNoncestr());
			packageParams.put("out_trade_no", orderNo);// 商户订单号
			packageParams.put("total_fee", totalFee);// 总金额
			String ip = IpAddressUtil.getHostIp();
			packageParams.put("spbill_create_ip", ip);// 发起人IP地址
			packageParams.put("body", subject);
			packageParams.put("auth_code", authCode);
			String sign = PayCommonUtil.createSign("UTF-8", packageParams,
					wxConfigUtil.getAPI_KEY());
			packageParams.put("sign", sign);// 签名
			String requestXML = PayCommonUtil.getRequestXml(packageParams);
			Object object = null;
			/**
			 * 将订单内容入库
			 */
			PayOrder payOrder = new PayOrder();
			payOrder.setOutTradeNo(orderNo);
			payOrder.setTotalAmount(new BigDecimal(totalAmount));
			payOrder.setCreateTime(LocalDateTime.now());
			payOrder.setSubject(subject);
			payOrder.setPayType(Integer.parseInt(payVO.getPayType()));
			payOrder.setPayStatus(2);
			payOrder.setPaymentMethod(1);
			payOrderMapper.insert(payOrder);
			//调微信统一下单接口
			String resXml = HttpUtil.postData(WxConfigUtil.PAYCODE_URL, requestXML);
			Map map = XMLUtil.doXMLParse(resXml);
			logger.debug("map:" + map);
			String returnCode = (String) map.get("return_code");
			String returnMsg = (String) map.get("return_msg");
			Map<String, Object> respMap = new HashedMap();
			//创建用户信息实体类

			if ("SUCCESS".equals(returnCode)) {
				//调用成功
				String resultCode = (String) map.get("result_code");
				String errCodeDes = (String) map.get("err_code_des");
				String errCode = (String) map.get("err_code");
				if ("SUCCESS".equals(resultCode)) {
					logger.info("付款码支付成功", orderNo, DateUtils.formatDateTime(new Date()));
					PayOrder payOrder1 = new PayOrder();
					payOrder1.setId(payOrder.getId());
					payOrder1.setCode(returnCode);
					payOrder1.setMessage(returnMsg);
					payOrder1.setPayStatus(1);
					payOrder1.setTradeNo((String) map.get("transaction_id"));
					String payTime = (String) map.get("time_end");
					DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
					payOrder1.setGmtPayment(LocalDateTime.parse(payTime,df));
					payOrderMapper.updateById(payOrder1);
					return ResultDataDto.ok("微信付款码支付成功", respMap);
				} else if ("USERPAYING".equals(errCode)) {
					logger.error("订单号:{}错误信息:{}", orderNo, errCodeDes);
					int result = triningService.payTraining(orderNo, payVO.getPayType());
					switch (result) {
						case 200:
							return ResultDataDto.ok("微信支付成功！", respMap);
						case 201:
							return new ResultDataDto("201", "超时支付订单关闭", respMap);
						case 500:
							return new ResultDataDto("500", "未知异常", respMap);
						case 501:
							return new ResultDataDto("501", "订单长时间未支付撤销订单操作失败", respMap);
						default:
							return new ResultDataDto("500", "未知异常", respMap);
					}
				} else {
					logger.error("订单号:{}错误信息:{}", orderNo, errCodeDes);
					return ResultDataDto.error(respMap);
				}
			} else {
				logger.error("订单号:{}错误信息:{}", orderNo, returnMsg);
				return ResultDataDto.error(respMap);
			}
		} catch (JDOMException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return ResultDataDto.error("异常失败");
	}
}
